package com.veer.shop.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import com.veer.shop.config.OpResult;

/**
 * Excel文件工具类
 * 
 * @author WangBin
 * 2020年12月31日-下午2:34:09
 */
public class ExcelUtil {
	
	/**
	 * 读取Excel文件数据
	 * 
	 * @param filename
	 * @param startLine
	 * @param tpl 导入Excel文件的表头
	 * @return List
	 */
	public static OpResult<List<Map<Integer, String>>> read(String filename, List<String> tplFields, Integer startLine) {
		OpResult<List<Map<Integer, String>>> excelReadResut = new OpResult<List<Map<Integer, String>>>();
		try {
			// 检查文件是否存在
			File file = new File(filename);
			if(!file.exists()) {
				throw new Exception("文件不存在");
			}
			
			// 读取文件
			InputStream inputStream = new FileInputStream(file);
			Workbook workbook = WorkbookFactory.create(inputStream);
			// 存储所有读取数据的list
			List<Map<Integer, String>> data = new ArrayList<Map<Integer, String>>();
			// 只读取第一个工作表
			Sheet sheet = workbook.getSheetAt(0);
			// 校验sheet
			if(sheet == null) {
				throw new Exception("获取Sheet失败");
			}
			// 检测非必填项的Map
			Map<Integer, Boolean> requiredMap = new HashMap<Integer, Boolean>();
			// 读取第一行表头，校验表头是否与系统设置符合
			int firstRowNum = sheet.getFirstRowNum();
			Row firstRow = sheet.getRow(firstRowNum);
			for(int i = 0; i < firstRow.getLastCellNum(); i++) {
				// 不存在则说明导入的文件与系统要求不符
				if(!tplFields.contains(convertCellValueToString(firstRow.getCell(i)))) {
					throw new Exception("使用系统提供的模板导入数据");
				}
				// 赋值必填Map，中文字段中包含星号(*)说明该项必填
				requiredMap.put(i, tplFields.get(i).contains("*"));
			}

			// 获取全部数据
			for(int rowNum = startLine; rowNum < sheet.getPhysicalNumberOfRows(); rowNum++) {
				// 存储行数据的list
				Map<Integer, String> rowData = new HashMap<Integer, String>();
				Row row = sheet.getRow(rowNum);
				for(int i = 0; i < row.getLastCellNum(); i++) {
					// 必填值校验
					if(requiredMap.get(i) && convertCellValueToString(row.getCell(i)) == null) {
						throw new Exception("第" + rowNum + "行必填数据不可为空");
					}
					rowData.put(i, convertCellValueToString(row.getCell(i)));
				}
				data.add(rowData);
			}
			
			// 读取数据为空
			if(data.isEmpty()) {
				throw new Exception("读取的数据为空");
			}
			
			excelReadResut.setFlag(true);
			excelReadResut.setMessage("Excel文件读取完毕");
			excelReadResut.setData(data);
		} catch (Exception e) {
			excelReadResut.setMessage("读取文件异常：" + e.getMessage());
			e.printStackTrace();
		}
		
		return excelReadResut;
	}
	
	/**
	 * 根据Excel单元格格式转化数据
	 * 
	 * @param cell
	 * @return
	 */
	public static String convertCellValueToString(Cell cell) {
		String cellValue = null;
		if(cell == null)return cellValue;
		
		switch (cell.getCellType()) {
			case NUMERIC:
				// 数字
				Double doubleValue = cell.getNumericCellValue();
                // 格式化科学计数法，取一位整数，如取小数，值如0.0,取小数点后几位就写几个0
                DecimalFormat df = new DecimalFormat("0");
                cellValue = df.format(doubleValue);
				break;
			case STRING:
				// 文本
				cellValue = cell.getStringCellValue();
				break;
			case BOOLEAN:
				//布尔
                Boolean booleanValue = cell.getBooleanCellValue();
                cellValue = booleanValue.toString();
                break;
            case BLANK:
            	// 空值
                break;
            case FORMULA:
            	// 公式
                cellValue = cell.getCellFormula();
                break;
			default:
				break;
		}
		return cellValue;
	}
}
